package com.rfid.project.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;

import biz.util.*;

import com.rfid.project.model.*;
import com.rfid.project.dao.*;
import com.rfid.project.exception.CannotUpdateException;
import com.mysema.query.BooleanBuilder;

import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Service
@Transactional
public class ProjectMilestoneFinishApplyService {

	@Autowired
	private ProjectMilestoneFinishApplyDao projectMilestoneFinishApplyDao;

	private QProjectMilestoneFinishApply $ = QProjectMilestoneFinishApply.projectMilestoneFinishApply;

	@Autowired
	public void setProjectMilestoneFinishApplyDao(
			ProjectMilestoneFinishApplyDao projectMilestoneFinishApplyDao) {
		this.projectMilestoneFinishApplyDao = projectMilestoneFinishApplyDao;
	}

	@Autowired
	private ProjectStakeholderDao projectStakeholderDao;
	
	private QProjectStakeholder $_projectStakeholder = QProjectStakeholder.projectStakeholder;
	
	@Autowired
	public void setProjectStakeholderDao(ProjectStakeholderDao projectStakeholderDao) {
		this.projectStakeholderDao = projectStakeholderDao;
	}

	@Autowired
	private ProjectMilestoneDao projectMilestoneDao;

	private QProjectMilestone $_projectMilestone = QProjectMilestone.projectMilestone;

	@Autowired
	public void setProjectMilestoneDao(ProjectMilestoneDao projectMilestoneDao) {
		this.projectMilestoneDao = projectMilestoneDao;
	}

	public List<ProjectMilestoneFinishApply> findAll() {
		return ListUtil.toList(projectMilestoneFinishApplyDao.findAll());
	}

	public List<ProjectMilestoneFinishApply> findAll(Long applyPersonId,
			String applyDescription, Date applyTimeBegin, Date applyTimeEnd,
			Long checkPersonId, String checkComment, Date checkTimeBegin,
			Date checkTimeEnd, String status, Long projectMilestoneId,
			String orderByAttribute) {
		BooleanBuilder condition = new BooleanBuilder();

		if (IdUtil.isNotEmpty(applyPersonId)) {
			condition.and($.applyPerson.id.eq(applyPersonId));
		}

		if (StringUtil.isNotEmpty(applyDescription)) {
			condition.and($.applyDescription.contains(applyDescription));
		}

		if (applyTimeBegin != null) {
			condition.and($.applyTime.after(applyTimeBegin));
		}

		if (applyTimeEnd != null) {
			condition.and($.applyTime.before(applyTimeEnd));
		}

		if (IdUtil.isNotEmpty(checkPersonId)) {
			condition.and($.checkPerson.id.eq(checkPersonId));
		}

		if (StringUtil.isNotEmpty(checkComment)) {
			condition.and($.checkComment.contains(checkComment));
		}

		if (checkTimeBegin != null) {
			condition.and($.checkTime.after(checkTimeBegin));
		}

		if (checkTimeEnd != null) {
			condition.and($.checkTime.before(checkTimeEnd));
		}

		if (StringUtil.isNotEmpty(status)) {
			condition.and($.status.contains(status));
		}

		if (IdUtil.isNotEmpty(projectMilestoneId)) {
			condition.and($.projectMilestone.id.eq(projectMilestoneId));
		}

		return ListUtil.toList(projectMilestoneFinishApplyDao
				.findAll(condition));
	}

	public Page<ProjectMilestoneFinishApply> findAll(Long applyPersonId,
			String applyDescription, Date applyTimeBegin, Date applyTimeEnd,
			Long checkPersonId, String checkComment, Date checkTimeBegin,
			Date checkTimeEnd, String status, Long projectMilestoneId,
			int pageNumber, int pageSize, String sortAttribute,
			String orderDirection) {
		BooleanBuilder condition = new BooleanBuilder();

		if (IdUtil.isNotEmpty(applyPersonId)) {
			condition.and($.applyPerson.id.eq(applyPersonId));
		}
		if (StringUtil.isNotEmpty(applyDescription)) {
			condition.and($.applyDescription.contains(applyDescription));
		}
		if (applyTimeBegin != null) {
			condition.and($.applyTime.after(applyTimeBegin));
		}

		if (applyTimeEnd != null) {
			condition.and($.applyTime.before(applyTimeEnd));
		}
		if (IdUtil.isNotEmpty(checkPersonId)) {
			condition.and($.checkPerson.id.eq(checkPersonId));
		}
		if (StringUtil.isNotEmpty(checkComment)) {
			condition.and($.checkComment.contains(checkComment));
		}
		if (checkTimeBegin != null) {
			condition.and($.checkTime.after(checkTimeBegin));
		}

		if (checkTimeEnd != null) {
			condition.and($.checkTime.before(checkTimeEnd));
		}
		if (StringUtil.isNotEmpty(status)) {
			condition.and($.status.contains(status));
		}
		if (IdUtil.isNotEmpty(projectMilestoneId)) {
			condition.and($.projectMilestone.id.eq(projectMilestoneId));
		}

		Sort sortObject = null;
		if (StringUtil.isEmpty(sortAttribute)) {
			sortObject = new Sort(Direction.DESC, "id");
		} else {
			sortObject = new Sort(Direction.fromStringOrNull(orderDirection),
					sortAttribute);
		}

		PageRequest pageRequest = new PageRequest(pageNumber - 1, pageSize,
				sortObject);
		return projectMilestoneFinishApplyDao.findAll(condition, pageRequest);
	}

	public ProjectMilestoneFinishApply getProjectMilestoneFinishApply(Long id) {
		return projectMilestoneFinishApplyDao.getOne(id);
	}

	public void deleteProjectMilestoneFinishApply(Long id) {
		projectMilestoneFinishApplyDao.delete(id);
	}

	public void saveProjectMilestoneFinishApply(ProjectMilestoneFinishApply projectMilestoneFinishApply) {
		if(null == projectMilestoneFinishApply.getApplyTime()){
			projectMilestoneFinishApply.setApplyTime(DateUtil.nowDate());
		}
		
		ProjectMilestone projectMilestone = this.projectMilestoneDao.findOne(projectMilestoneFinishApply.getProjectMilestone().getId());
		projectMilestone.setStatus(projectMilestoneFinishApply.getProjectMilestone().getStatus());
		
		this.projectMilestoneFinishApplyDao.save(projectMilestoneFinishApply);
		this.projectMilestoneDao.save(projectMilestone);
	}

	public List<ProjectMilestoneFinishApply> findByStatus(People people, Long ProjectStakeholderType, String status, String qualityCheckSign) {
		BooleanBuilder condition = new BooleanBuilder();
		condition.and(this.$_projectStakeholder.personID.eq(people.getId()));
		condition.and(this.$_projectStakeholder.projectStakeholderType.id.eq(ProjectStakeholderType));
		Iterable<ProjectStakeholder> iterable = this.projectStakeholderDao.findAll(condition);
		Set<Long> projectIds = new HashSet<Long>();
		for (ProjectStakeholder projectStakeholder : iterable) {
			projectIds.add(projectStakeholder.getProject().getId());
		}
		
		if(!projectIds.isEmpty()){
			condition = new BooleanBuilder();
			condition.and(this.$.projectMilestone.project.id.in(projectIds));
			if (StringUtil.isNotEmpty(status)) {
				condition.and($.status.eq(status));
			}
			if(StringUtil.isNotEmpty(qualityCheckSign)){
				condition.and(this.$.projectMilestone.qualityCheckSign.eq(qualityCheckSign));
			}
			return ListUtil.toList(projectMilestoneFinishApplyDao.findAll(condition));
		}
		return null;
	}

	public void revocationFinishApplyProjectMilestoneFinishApply(ProjectMilestoneFinishApply projectMilestoneFinishApply) throws CannotUpdateException {
		ProjectMilestoneFinishApply sourceProjectMilestoneFinishApply = this.projectMilestoneFinishApplyDao.findOne(projectMilestoneFinishApply.getId());
		if(!ProcessStatus.FINISH_APPLY.equals(sourceProjectMilestoneFinishApply.getStatus())){
			throw new CannotUpdateException("项目节点完成申请已发生变化，请刷新后再试！");
		}
		sourceProjectMilestoneFinishApply.setStatus(projectMilestoneFinishApply.getStatus());
		sourceProjectMilestoneFinishApply.setAnnulDate(DateUtil.nowDate());
		
		ProjectMilestone projectMilestone = sourceProjectMilestoneFinishApply.getProjectMilestone();
		projectMilestone.setStatus(projectMilestoneFinishApply.getProjectMilestone().getStatus());
		
		this.projectMilestoneFinishApplyDao.save(sourceProjectMilestoneFinishApply);
		this.projectMilestoneDao.save(projectMilestone);
	}

	public void qualityCheckProjectMilestoneFinishApply(ProjectMilestoneFinishApply projectMilestoneFinishApply) throws CannotUpdateException {
		ProjectMilestoneFinishApply sourceProjectMilestoneFinishApply = this.projectMilestoneFinishApplyDao.findOne(projectMilestoneFinishApply.getId());
		if(!ProcessStatus.FINISH_APPLY.equals(sourceProjectMilestoneFinishApply.getStatus())){
			throw new CannotUpdateException("项目节点完成申请已发生变化，请刷新后再试！");
		}
		sourceProjectMilestoneFinishApply.setStatus(projectMilestoneFinishApply.getStatus());
		sourceProjectMilestoneFinishApply.setQualityCheckDate(projectMilestoneFinishApply.getQualityCheckDate());
		sourceProjectMilestoneFinishApply.setQualityCheckDescription(projectMilestoneFinishApply.getQualityCheckDescription());
		sourceProjectMilestoneFinishApply.setQualityCheckInputTime(DateUtil.nowDate());
		sourceProjectMilestoneFinishApply.setQualityCheckPerson(projectMilestoneFinishApply.getQualityCheckPerson());
		sourceProjectMilestoneFinishApply.setQualityCheckStatus(projectMilestoneFinishApply.getQualityCheckStatus());
		
		ProjectMilestone projectMilestone = sourceProjectMilestoneFinishApply.getProjectMilestone();
		projectMilestone.setStatus(projectMilestoneFinishApply.getProjectMilestone().getStatus());

		this.projectMilestoneFinishApplyDao.save(sourceProjectMilestoneFinishApply);
		this.projectMilestoneDao.save(projectMilestone);
	}

	public void checkProjectMilestoneFinishApply(ProjectMilestoneFinishApply projectMilestoneFinishApply) throws CannotUpdateException {
		ProjectMilestoneFinishApply sourceProjectMilestoneFinishApply = this.projectMilestoneFinishApplyDao.findOne(projectMilestoneFinishApply.getId());
		ProjectMilestone projectMilestone = sourceProjectMilestoneFinishApply.getProjectMilestone();
		String status = sourceProjectMilestoneFinishApply.getStatus();
		if(("N".equals(projectMilestone.getQualityCheckSign()) && !ProcessStatus.FINISH_APPLY.equals(status)) || ("Y".equals(projectMilestone.getQualityCheckSign()) && !ProcessStatus.QUALITY_SUCCESS.equals(status))){
			throw new CannotUpdateException("项目节点完成申请已发生变化，请刷新后再试！");
		}
		sourceProjectMilestoneFinishApply.setCheckTime(DateUtil.nowDate());
		sourceProjectMilestoneFinishApply.setCheckPerson(projectMilestoneFinishApply.getCheckPerson());
		sourceProjectMilestoneFinishApply.setCheckComment(projectMilestoneFinishApply.getCheckComment());
		sourceProjectMilestoneFinishApply.setStatus(projectMilestoneFinishApply.getStatus());
		
		if(ProcessStatus.EXAMINE_SUCCESS.equals(projectMilestoneFinishApply.getStatus())){
			projectMilestone.setActualFinishDate(DateUtil.nowDate());
		}
		projectMilestone.setStatus(projectMilestoneFinishApply.getProjectMilestone().getStatus());
		
		this.projectMilestoneFinishApplyDao.save(sourceProjectMilestoneFinishApply);
		this.projectMilestoneDao.save(projectMilestone);
	}

}
